using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using DealerPlatform.Core.Repository;
using DealerPlatform.Domain;
using Microsoft.Extensions.DependencyInjection;

namespace DealerPlatform.Extensions
{

    public static class ServiceCollectionExtensions
    {
        /// <summary>
        /// 注册仓储
        /// 该方法中使用了固定的类名称：typeof(IRepository<>)和Repository`1，意义不大
        /// </summary>
        /// <param name="services"></param>
        /// <returns></returns>
        public static IServiceCollection RepositoryRegister(this IServiceCollection services)
        {
            var asmCore = Assembly.Load("DealerPlatform.Core");

            // 也可加载
            // string assemblyPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "DealerPlatform.Core.dll");
            // var asmCore2 = Assembly.LoadFrom(assemblyPath);

            var implementationType = asmCore.GetTypes().FirstOrDefault(m => m.Name == "Repository`1");
            var interfaceType = implementationType?.GetInterface("IRepository`1");
            if (interfaceType != null && implementationType != null)
            {
                // services.AddTransient(interfaceType, implementationType);
                services.AddTransient(typeof(IRepository<>), implementationType);   //只能这么些，否则Build时会出现不能构造的问题！
            }
            return services;
        }

        /// <summary>
        /// 注册仓储
        /// 该方法中使用了固定的类名称：typeof(IRepository)和typeof(IRepository<>)，意义不大
        /// </summary>
        /// <param name="services"></param>
        /// <returns></returns>
        public static IServiceCollection RepositoryRegister2(this IServiceCollection services)
        {
            var asmCore = Assembly.Load("DealerPlatform.Core");
            var implementationTypes = asmCore.GetTypes().Where(
                t => t.IsAssignableTo(typeof(IRepository)) &&
                !t.IsInterface &&
                !t.IsAbstract);

            foreach (var implementationType in implementationTypes)
            {
                services.AddTransient(typeof(IRepository<>), implementationType);
            }
            return services;
        }

        /// <summary>
        /// 注册服务
        /// </summary>
        /// <param name="services"></param>
        /// <returns></returns>
        public static IServiceCollection ServicesRegister(this IServiceCollection services)
        {
            var asmService = Assembly.Load("DealerPlatform.Service");
            var implementationTypes = asmService.GetTypes().Where(
                t => t.IsAssignableTo(typeof(IocTag)) &&
                !t.IsInterface &&
                !t.IsAbstract);

            foreach (var implementationType in implementationTypes)
            {
                var interfaceType = implementationType.GetInterfaces().Where(
                    i => i != typeof(IocTag)).FirstOrDefault();
                if (interfaceType != null)
                    services.AddTransient(interfaceType, implementationType);
            }
            return services;
        }
    }
}